package com.veeder.datacollection.rs232.response.handler;


import java.util.Calendar;
import java.util.Date;
import com.veeder.datacollection.exception.SyntaxException;
import com.veeder.datacollection.rs232.response.BasicTankInventory;
import com.veeder.datacollection.rs232.response.TankResponseReport;
import com.veeder.datacollection.util.DataUtil;
import com.veeder.datacollection.util.DateUtil;

public class RS201RspHandler extends CmdRspParser {
	private final static RS201RspHandler instance = new RS201RspHandler();
	
	private RS201RspHandler() {
		super();
	}

	public static RS201RspHandler getInstance() {
		return instance;
	}


	private int findNumberOfTanks(String coreResponse) {

		int NNPosition = 16;
		int noOfTanks = 0;
		while (NNPosition < coreResponse.length()) {
			NNPosition += 7;
			String dataFieldsLenStr = coreResponse.substring(NNPosition, NNPosition += 2);
			int dataFieldsLen = Integer.parseInt(dataFieldsLenStr, 16);
			NNPosition += (dataFieldsLen * 8);
			noOfTanks++;
		}

		return noOfTanks;
	}

	private Date getSystemTimeIn30SecondsFormat() {
		Calendar calendar = Calendar.getInstance();	
		int seconds = calendar.get(Calendar.SECOND);
		if (seconds > 45) {
			calendar.set(Calendar.MINUTE, calendar.get(Calendar.MINUTE) + 1);
			calendar.set(Calendar.SECOND, 0);
		} else if (seconds < 45 && seconds > 15) {
			calendar.set(Calendar.SECOND, 30);
		} else {
			calendar.set(Calendar.SECOND, 0);
		}
		return calendar.getTime();
	}

	@Override
	public TankResponseReport<BasicTankInventory> parseCoreResponse(String response) throws SyntaxException {
		TankResponseReport<BasicTankInventory> result = null;
		try {
			result = new TankResponseReport<BasicTankInventory>();

			int position = 6;
			result.setTlsSysDate(DateUtil.convertToDate(response.substring(position,position+=10),DateUtil.DateFormat1));

			int totalTanks = findNumberOfTanks(response);
			for (int i = 0; i < totalTanks; i++) {
				BasicTankInventory tankInventory = new BasicTankInventory();
				String tankNoStr = response.substring(position, position += 2);
				int tankNo = Integer.parseInt(tankNoStr);
				tankInventory.setTankNo(tankNo);

				tankInventory.setSampleTime(getSystemTimeIn30SecondsFormat());

				String productCodeStr = response.substring(position, position += 1);
				tankInventory.setProductCode(productCodeStr);
				String tankStatus = response.substring(position, position += 4);
				tankInventory.setTankStatus(tankStatus);

				String fieldCountStr = response.substring(position, position += 2);
				int fieldCount = Integer.parseInt(fieldCountStr, 16);

				final int FixedFieldCount = 7;
				if (fieldCount >= FixedFieldCount) {
					for (int index = 0; index < FixedFieldCount; index++) {
						String floatStr = response.substring(position, position += 8);
						float dataValue = DataUtil.hexToFloat(floatStr);

						switch (index) {
						case 0:
							tankInventory.setVolume(dataValue);
							break;
						case 1:
							tankInventory.setTcVolume(dataValue);
							break;
						case 2:
							tankInventory.setUllage(dataValue);
							break;
						case 3:
							tankInventory.setHeight(dataValue);
							break;
						case 4:
							tankInventory.setWaterHeight(dataValue);
							break;
						case 5:
							tankInventory.setTemperature(dataValue);
							break;
						case 6:
							tankInventory.setWaterVolume(dataValue);
							break;
						default:
							break;
						}
					}
				}
				result.setTankReponse(tankNo, tankInventory);
			} // for end
		} catch (Exception e) {
			new SyntaxException(e);
		}
		return result;
	}

}
